using System;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Net;
using System.Text;
using Subkismet.Properties;

namespace Subkismet
{
	/// <summary>
	/// Class used to make the actual HTTP requests.
	/// </summary>
	/// <remarks>
	/// Yeah, I know you're thinking this is overkill, but it makes it 
	/// easier to write tests to have this layer of abstraction from the 
	/// underlying Http request.
	/// </remarks>
	public class HttpClient
	{
		/// <summary>
		/// Posts the request and returns a text response.  
		/// This is all that is needed for Akismet.
		/// </summary>
		/// <param name="url">The URL.</param>
		/// <param name="userAgent">The user agent.</param>
		/// <param name="timeout">The timeout.</param>
		/// <param name="formParameters">The properly formatted parameters.</param>
		/// <returns></returns>
		public virtual string PostRequest(Uri url, string userAgent, int timeout, string formParameters)
		{
			return PostRequest(url, userAgent, timeout, formParameters, null);
		}

		/// <summary>
		/// Posts the request.
		/// </summary>
		/// <param name="url">The URL.</param>
		/// <param name="userAgent">The user agent.</param>
		/// <param name="timeout">The timeout in milliseconds.</param>
		/// <param name="formParameters">The form parameters.</param>
		/// <param name="proxy">The proxy.</param>
		/// <returns></returns>
		public virtual string PostRequest(Uri url, string userAgent, int timeout, string formParameters, IWebProxy proxy)
		{
			if (formParameters == null)
				throw new ArgumentNullException("formParameters", Resources.ArgumentNull_String);
			
			ServicePointManager.Expect100Continue = false;
			HttpWebRequest request = WebRequest.Create(url) as HttpWebRequest;

			Debug.Assert(request != null, "HttpWebRequest should not be null", string.Format("Calling WebRequest.Create(url) produced a null HttpWebRequest instance for the URL '{0}'", url));

			if (proxy != null)
				request.Proxy = proxy;
			
			request.UserAgent = userAgent;
			request.Timeout = timeout;
			request.Method = "POST";
			request.ContentLength = formParameters.Length;
			request.ContentType = "application/x-www-form-urlencoded; charset=utf-8";
			request.KeepAlive = true;

			using (StreamWriter myWriter = new StreamWriter(request.GetRequestStream()))
			{
				myWriter.Write(formParameters);
			}

			HttpWebResponse response = (HttpWebResponse)request.GetResponse();
			if (response.StatusCode < HttpStatusCode.OK && response.StatusCode >= HttpStatusCode.Ambiguous)
				throw new InvalidResponseException(string.Format(CultureInfo.InvariantCulture, Resources.InvalidResponse_Generic, response.StatusCode), response.StatusCode);

			string responseText;
			using(StreamReader reader = new StreamReader(response.GetResponseStream(), Encoding.ASCII)) //They only return "true" or "false"
			{
				responseText = reader.ReadToEnd();
			}
			
			return responseText;
		}


        /// <summary>
        /// Gets the content of a web page.
        /// </summary>
        /// <param name="url">The URL.</param>
        /// <param name="userAgent">The user agent.</param>
        /// <param name="timeout">The timeout in miliseconds.</param>
        /// <param name="proxy">The proxy.</param>
        /// <returns>The string value of requested web page.</returns>
        public virtual string GetRequest(Uri url, string userAgent, int timeout, IWebProxy proxy)
        {
            ServicePointManager.Expect100Continue = false;
            HttpWebRequest request = WebRequest.Create(url) as HttpWebRequest;

            Debug.Assert(request != null, "HttpWebRequest should not be null", string.Format("Calling WebRequest.Create(url) produced a null HttpWebRequest instance for the URL '{0}'", url));

            if (proxy != null)
                request.Proxy = proxy;

            request.UserAgent = userAgent;
            request.Timeout = timeout;
            request.Method = "GET";
            request.ContentType = "application/x-www-form-urlencoded; charset=utf-8";
            request.KeepAlive = true;

            HttpWebResponse response = (HttpWebResponse)request.GetResponse();
            if (response.StatusCode < HttpStatusCode.OK && response.StatusCode >= HttpStatusCode.Ambiguous)
                throw new InvalidResponseException(string.Format(CultureInfo.InvariantCulture, Resources.InvalidResponse_Generic, response.StatusCode), response.StatusCode);

            string responseText;
            using (StreamReader reader = new StreamReader(response.GetResponseStream(), Encoding.ASCII)) //They only return "true" or "false"
            {
                responseText = reader.ReadToEnd();
            }

            return responseText;
        }
	}
}
